package com.verysimple.flipcard
{
	import com.verysimple.skins.RoundedCornersBL;
	
	import flash.utils.setTimeout;
	
	import mx.containers.Box;
	import mx.containers.HBox;
	import mx.containers.ViewStack;
	import mx.controls.Button;
	import mx.controls.Label;
	import mx.core.UIComponent;
	import mx.events.FlexEvent;
	
	import ws.tink.flex.pv3dEffects.*;
	
	public class FlipCard extends ViewStack
	{
		private var animationHideFront:Flip;
		private var animationShowFront:Flip;
		private var animationShowBack:Flip;
		private var animationHideBack:Flip;
		private var flipCardContainer:HBox;
		private var flipButton:Button;
		
		private var front:UIComponent;
		private var back:UIComponent;
		private var backRendered:Boolean = false;
		
		public var flipSpeed:int = 250;
		
		public function FlipCard()
		{
			this.resizeToContent = true;
			
			this.addEventListener(FlexEvent.CREATION_COMPLETE, onCreationComplete);
			
			super();
		}
		
		/**
		 * Fires on FlexEvent.CREATION_COMPLETE
		 */
		private function onCreationComplete(event:FlexEvent):void
		{
			// trace("FlipCard.onCreationComplete");
			
			// make sure there are at least 2 children to prevent null errors
			var numChildren:int = (this.childDescriptors != null) ? this.childDescriptors.length : 0;
			for (var i:int = numChildren; i <= 2; i++)
			{
				this.addPlaceHolderChild();
			}
			
			front = this.getChildAt(0) as UIComponent;
			back = this.getChildAt(1) as UIComponent;
			
			this.initStyles();
			this.initAnimations();
			
		}

		/**
		 * Assigns the approp styleNames to all the objects
		 */
		private function initStyles():void
		{
			if (this.styleName == null) this.styleName = "FlipCard";
			if (front.styleName == null) front.styleName = "FlipCardFront";
			if (back.styleName == null) back.styleName = "FlipCardBack";

		}
		
		/**
		 * Initializes all of the animation effect objects and binds them to the front/back
		 */
		private function initAnimations():void
		{
			animationHideFront = createFlipAnimation(true,Flip.HIDE,Flip.LEFT,this.flipSpeed);
			animationShowFront = createFlipAnimation(true,Flip.SHOW,Flip.RIGHT,this.flipSpeed);
			animationShowBack = createFlipAnimation(true,Flip.SHOW,Flip.LEFT,this.flipSpeed);
			animationHideBack = createFlipAnimation(true,Flip.HIDE,Flip.RIGHT,this.flipSpeed);

			
			front.setStyle("showEffect",animationShowFront);
			front.setStyle("hideEffect",animationHideFront);
			back.setStyle("showEffect",animationShowBack);
			back.setStyle("hideEffect",animationHideBack);

		}
		
		/**
		 * Toggle the card between the front and back
		 */
		public function toggle(event:FlexEvent = null):void
		{
			if (backRendered)
			{
				doToggle();
			}
			else
			{
				trace("FlipCard.toggle: Rendering components on backside of card...");

				// setTimout will add the animation to the end of the worker queue behind component rendering
				setTimeout(doToggle, 100 );
				backRendered = true;
			}
		}
		
		/**
		 * Function that actually initiates the toggle
		 */
		private function doToggle():void
		{
			this.selectedIndex = (this.selectedIndex == 0) ? 1 : 0;
		}
		
		/**
		 * adds a placeholder child in the event that the user did not drag two components
		 * inside.
		 */
		private function addPlaceHolderChild():void
		{
			var box:Box = new Box();
			var lbl:Label = new Label;
			lbl.setStyle("backgroundColor","ffaaaa");
			lbl.text = "Drag a UIComponent here..."
			this.addChild(box);
		}
		
		/**
		 * Utility function to create the flip animation object w/ properties pre-configured
		 */
		private function createFlipAnimation(constrain:Boolean,flipType:String,direction:String,duration:Number):Flip
		{
			var flip:Flip = new Flip();
			flip.constrain = constrain;
			flip.type = flipType;
			flip.direction = direction;
			flip.duration = duration;
			return flip;
		}
		
	}
}